// function.go
package main

import (
	"math"
)

type FuncIndex int

const (
	SysFunc_cos     FuncIndex = 100
	SysFunc_sin     FuncIndex = 101
	SysFunc_tan     FuncIndex = 102
	SysFunc_exp     FuncIndex = 103
	SysFunc_log     FuncIndex = 104
	SysFunc_log2    FuncIndex = 105
	SysFunc_log10   FuncIndex = 106
	SysFunc_pow     FuncIndex = 107
	SysFunc_abs     FuncIndex = 108
	SysFunc_div     FuncIndex = 109
	SysFunc_add     FuncIndex = 110
	SysFunc_addset  FuncIndex = 111
	SysFunc_sub     FuncIndex = 112
	SysFunc_mul     FuncIndex = 113
	SysFunc_assign  FuncIndex = 114
	SysFunc_asin    FuncIndex = 115
	SysFunc_acos    FuncIndex = 116
	SysFunc_atan    FuncIndex = 117
	SysFunc_erf     FuncIndex = 118
	SysFunc_gamma   FuncIndex = 119
	SysFunc_round   FuncIndex = 120
	SysFunc_floor   FuncIndex = 121
	SysFunc_sign    FuncIndex = 122
	SysFunc_max     FuncIndex = 123
	SysFunc_min     FuncIndex = 124
	SysFunc_mod     FuncIndex = 125
	SysFunc_sqrt    FuncIndex = 126
	SysFunc_larger  FuncIndex = 127
	SysFunc_equal   FuncIndex = 128
	SysFunc_largEqu FuncIndex = 129
	SysFunc_smaller FuncIndex = 130
	SysFunc_smalEqu FuncIndex = 131
	SysFunc_notEqu  FuncIndex = 132
	SysFunc_not     FuncIndex = 133
	SysFunc_or      FuncIndex = 134
	SysFunc_and     FuncIndex = 135
	SysFunc_random  FuncIndex = 136
	SysFunc_print   FuncIndex = 137
	SysFunc_return  FuncIndex = 138
	SysFunc_list    FuncIndex = 139
	SysFunc_tuple   FuncIndex = 140
	SysFunc_dict    FuncIndex = 141
	SysFunc_range   FuncIndex = 142
	SysFunc_pair    FuncIndex = 143
	SysFunc_getItem FuncIndex = 144
	SysFunc_setItem FuncIndex = 145
	SysFunc_import  FuncIndex = 146
	SysFunc_dir     FuncIndex = 147
	SysFunc_array   FuncIndex = 148
	SysFunc_file    FuncIndex = 149
	SysFunc_map     FuncIndex = 150
	SysFunc_ones    FuncIndex = 151
	SysFunc_int     FuncIndex = 152
	SysFunc_float   FuncIndex = 153
	SysFunc_str     FuncIndex = 154
	SysFunc_len     FuncIndex = 155
	SysFunc_arange  FuncIndex = 156

	SysFunc_generic FuncIndex = 300
)

/*****************************Function****************************/
type DrFunction struct {
	DrAbstractObject
	Name        string
	index       FuncIndex
	Father      *DrClass //函数所属的类，如果没有所属类，则为空
	ParamNames  []string
	returnNames []string
	RealParams  []*DrAbstractObject
	Result      *DrAbstractObject
	Clauses     []*DrClause
	Value       string
	module      *DrModule
}

func NewFunction(name string, params []string) *DrFunction {
	func0 := new(DrFunction)
	func0.Name = name
	func0.ParamNames = params

	func0.Type = TypeBuiltInFunc
	return func0
}
func (self *Interpreter) NewFunction(name string, params []string, father *DrClass) IObject {
	func0 := new(DrFunction)
	func0.Father = father
	func0.Name = name
	func0.ParamNames = params
	func0.Type = TypeBuiltInFunc
	return func0
}
func (self *DrFunction) Execute(params []IObject) IObject {
	var v float64
	if params[0].getType() == TypeNum {
		v = params[0].getDouble()

		if self.Name == "cos" {
			return NewNum(math.Cos(v))

		} else if self.Name == "add" {
			v := params[0].getDouble()
			v2 := params[1].getDouble()

			r := NewNum(v + v2)
			return r

		}
	}

	return nil
}

func (self *DrFunction) AddParaName(name string) {
	self.ParamNames = append(self.ParamNames, name)
}
func (this *Interpreter) InitSysFuncs() map[string]FuncIndex {
	bafuncs := make(map[string]FuncIndex)
	bafuncs["assign"] = SysFunc_assign
	bafuncs["set"] = SysFunc_assign
	bafuncs["addset"] = SysFunc_addset
	bafuncs["abs"] = SysFunc_abs
	bafuncs["cos"] = SysFunc_cos
	bafuncs["sin"] = SysFunc_sin
	bafuncs["tan"] = SysFunc_tan
	bafuncs["asin"] = SysFunc_asin
	bafuncs["acos"] = SysFunc_acos
	bafuncs["atan"] = SysFunc_atan
	bafuncs["add"] = SysFunc_add
	bafuncs["sub"] = SysFunc_sub
	bafuncs["mul"] = SysFunc_mul
	bafuncs["div"] = SysFunc_div
	bafuncs["pow"] = SysFunc_pow
	bafuncs["exp"] = SysFunc_exp
	bafuncs["log"] = SysFunc_log
	bafuncs["log2"] = SysFunc_log2
	bafuncs["log10"] = SysFunc_log10
	bafuncs["larger"] = SysFunc_larger
	bafuncs["largEq"] = SysFunc_largEqu
	bafuncs["smaller"] = SysFunc_smaller
	bafuncs["smalEq"] = SysFunc_smalEqu
	bafuncs["equal"] = SysFunc_equal
	bafuncs["unequal"] = SysFunc_notEqu
	bafuncs["erf"] = SysFunc_erf
	bafuncs["gamma"] = SysFunc_gamma
	bafuncs["round"] = SysFunc_round
	bafuncs["floor"] = SysFunc_floor
	bafuncs["sign"] = SysFunc_sign
	bafuncs["not"] = SysFunc_not
	bafuncs["or"] = SysFunc_or
	bafuncs["and"] = SysFunc_and
	bafuncs["max"] = SysFunc_max
	bafuncs["min"] = SysFunc_min
	bafuncs["mod"] = SysFunc_mod
	bafuncs["random"] = SysFunc_random
	bafuncs["print"] = SysFunc_print
	bafuncs["list"] = SysFunc_list
	bafuncs["tuple"] = SysFunc_tuple
	bafuncs["range"] = SysFunc_range
	bafuncs["arange"] = SysFunc_arange
	bafuncs["pair"] = SysFunc_pair
	bafuncs["getItem"] = SysFunc_getItem
	bafuncs["setItem"] = SysFunc_setItem
	bafuncs["dir"] = SysFunc_dir
	bafuncs["array"] = SysFunc_array
	bafuncs["file"] = SysFunc_file
	bafuncs["map"] = SysFunc_map
	bafuncs["ones"] = SysFunc_ones
	bafuncs["int"] = SysFunc_int
	bafuncs["float"] = SysFunc_float
	bafuncs["str"] = SysFunc_str
	bafuncs["len"] = SysFunc_len

	return bafuncs
}
